package com.study.kt._04project.game_tank.business

import com.study.kt._04project.game_tank.Config
import com.study.kt._04project.game_tank.enums.Direction
import com.study.kt._04project.game_tank.model.View

/**
 * 移动能力
 */
interface Moveable : View {
    //可移动的物体有位置、大小属性,所以可以让该接口继承View接口


    //可移动的物体还有自己的 当前移动方向、速度属性
    val currentDirection: Direction
    val speed: Int


    /**
     * 接收到碰撞的通知
     * @param blockable 碰撞到的阻挡物
     * @param direction 要碰撞的方向
     */

    fun notifyCollisition(blockable: Blockable?, direction: Direction?)


    /**
     * 可移动的物体有判断是否碰撞到到阻挡物体的能力
     *
     * @return 受碰撞的反向，如果为null说明没有碰撞
     */
    //我方坦克、地方坦克，都有判断碰撞方向的方法所以可以提取到父类中实现
    fun willCollision(blockable: Blockable): Direction? {

        //bugfix:在测试过程中发现，移动到碰撞物虽然不可以再次移动了，但是测试无论怎么转向都无法再次移动
        //分析问题：当前移动物体的x、y是加上speed后的位置，其实位置已经移动了，上下左右都到达边界，所以无法再次移动
        //问题解决：要使用移动物下一次的位置进行判断

        //为了不影响全局变量，此物我们单独提取变量计算
        var x: Int = this.x
        var y: Int = this.y
        when (currentDirection) {
            //移动的距离为速度
            Direction.UP -> y -= speed
            Direction.DOWN -> y += speed
            Direction.LEFT -> x -= speed
            Direction.RIGHT -> x += speed
        }

        //kotlin中when、if表达式的{}为一个闭包，最后一行即为返回值
        //此处要检测是否碰撞比较困难，因为重合大小、方向等各种情况，换位思考只要判断不碰撞的情况即可，剩下的都是碰撞

        /*val isCollision = when {
            //如果移动物体在碰撞物上面，只要满足移动物体y坐标+移动物体高度小于碰撞物y坐标即可
            y + height <= blockable.y -> false
            //移动物体在碰撞物下方
            blockable.y + blockable.height <= y -> false
            //移动物体在碰撞物左边
            x + width <= blockable.x -> false
            //移动物体在碰撞物右边
            blockable.x + blockable.width <= x -> false
            else -> true
        }*/

        //除了和碰撞物碰撞为错误方向，还需要和边界做校验，如果不做校验敌方坦克在碰撞到边界之后就不会移动了
        if (x < 0) return Direction.LEFT //当x小于0时，左边为错误边界方向
        if (y < 0) return Direction.UP
        if (x > Config.gameWidth - Config.block) return Direction.RIGHT
        if (y > Config.gameHeight - Config.block) return Direction.DOWN

        val isCollision =
            checkCollision(x, y, width, height, blockable.x, blockable.y, blockable.width, blockable.height)

        //如果放生碰撞则返回当前方向，如果没有碰撞返回null继续移动即可
        return if (isCollision) currentDirection else null
    }
}